package com.gitee.candy.desensitize.log;

import ch.qos.logback.classic.spi.LoggingEvent;
import ch.qos.logback.core.ConsoleAppender;

import java.lang.reflect.Field;

/**
 * @author suYanLong
 * @date 2023年01月09日 10:03
 */
public class SelfConsoleAppender extends ConsoleAppender {

    /**
     * LoggingEvent的属性 - message
     * 格式化前的日志信息，如log.info("your name : {}", "柳成荫")
     * message就是"your name : {}"
     */
    private static final String MESSAGE = "message";

    /**
     * LoggingEvent的属性 - formattedMessage
     * 格式化后的日志信息，如log.info("your name : {}", "柳成荫")
     * formattedMessage就是"your name : 柳成荫"
     */
    private static final String FORMATTED_MESSAGE = "formattedMessage";

    @Override
    protected void subAppend(Object event) {
        LoggingEvent loggingEvent = (LoggingEvent) event;
        Object[] argumentArray = loggingEvent.getArgumentArray();
        // event.getArgumentArray() - 获取日志中的参数数组
        // 如：log.info("your name : {}, your id : {}", "柳成荫", 11)
        // event.getArgumentArray() => ["柳成荫",11]
        if (loggingEvent.getArgumentArray() != null) {
            // 获取格式化后的Message
            String eventFormattedMessage = loggingEvent.getFormattedMessage();
//            DesensitizationUtil util = new DesensitizationUtil();
            // 获取替换后的日志信息
//            String changeMessage = util.customChange(eventFormattedMessage);
            if (eventFormattedMessage.contains("55555")) {
                String changeMessage = "666";
                if (!(null == changeMessage || "".equals(changeMessage))) {
                    try {
                        // 利用反射的方式，将替换后的日志设置到原event对象中去
                        Class<? extends LoggingEvent> eventClass = loggingEvent.getClass();
                        // 保险起见，将message和formattedMessage都替换了
                        Field message = eventClass.getDeclaredField(MESSAGE);
                        message.setAccessible(true);
                        message.set(loggingEvent, changeMessage);
                        Field formattedMessage = eventClass.getDeclaredField(FORMATTED_MESSAGE);
                        formattedMessage.setAccessible(true);
                        formattedMessage.set(loggingEvent, changeMessage);
                    } catch (IllegalAccessException | NoSuchFieldException e) {
                        e.printStackTrace();
                    }
                }
            }
            super.subAppend(loggingEvent);
        }
    }

}